import { truthy } from '@gnlab/utils'
import { Button, message, Popconfirm, Input, Form } from 'antd'
import { ImportantEditModal, Table } from '@/desktop/components'
import services from '@/services'
import type { MessageVariable } from '@/services/features/normal-welcome'
import './variables.module.less'

export default function Params() {
  // ========== 加载列表 ==========
  const [variables, setVariables] = useState<MessageVariable[]>([])
  const [loading, setLoading] = useState(false)
  const loadVariables = useCallback(async () => {
    setLoading(true)
    const res = await services.features.normalWelcome.loadVariables()
    if (res.success) setVariables(res.data)
    else void message.warning('获取变量列表失败')
    setLoading(false)
    return res.success
  }, [])

  useEffect(() => {
    void loadVariables()
  }, [loadVariables])

  // ========== 移除 ==========
  const [removing, setRemoving] = useState(false)
  const remove = useCallback(
    async (id: number) => {
      setRemoving(true)

      const res = await services.features.normalWelcome.removeVariable(id)
      if (res.success) void message.success('删除成功')
      else void message.warning(`删除失败：${res.error}`)

      await loadVariables()

      setRemoving(false)
    },
    [loadVariables],
  )

  // ========== 创建/编辑 ==========
  const [editing, setEditing] = useState<MessageVariable | true | null>(null)
  const finishEdit = useCallback(() => {
    setEditing(null)
    void loadVariables()
  }, [loadVariables])

  // ========== 界面 ==================

  const blocking = loading || removing

  const renderActions = useCallback(
    (variable: MessageVariable) => {
      return <>
        <Button type="link" onClick={() => setEditing(variable)}>
          修改
        </Button>
        <Popconfirm title="确定要删除此变量吗？" onConfirm={async () => remove(variable.id)}>
          <Button type="link" danger>
            删除
          </Button>
        </Popconfirm>
      </>
    },
    [remove],
  )

  return <div styleName="variables-wrap">
    <header>
      <Button type="primary" onClick={() => setEditing(true)}>
        新建变量
      </Button>
    </header>

    <Table<MessageVariable>
      rowKey="id"
      dataSource={variables}
      scroll={{ y: 300 }}
      pagination={false}
      loading={blocking}
    >
      <Table.Column<MessageVariable> title="变量名" width={180} dataIndex="name" />
      <Table.Column<MessageVariable> title="提取正则" width={200} dataIndex="regex" />
      <Table.Column<MessageVariable>
        title="操作"
        key="actions"
        width={160}
        styleName="actions"
        render={renderActions}
      />
    </Table>

    <EditVariableModal editing={editing} onFinish={finishEdit} />
  </div>
}

function EditVariableModal(props: {
  editing?: null | true | MessageVariable
  onFinish: () => void
}) {
  const { editing, onFinish } = props

  const title = truthy(editing) ? (editing === true ? '新建变量' : '编辑变量') : ''

  return <ImportantEditModal title={title} width="650px" open={truthy(editing)} onCancel={onFinish}>
    {truthy(editing) ? <EditContent editing={editing} onFinish={onFinish} /> : null}
  </ImportantEditModal>
}

const patternRule = {
  async validator(rule: unknown, value: string) {
    try {
      new RegExp(value)
    } catch (e) {
      return Promise.reject(new Error('正则表达式不合法'))
    }
  },
}

function EditContent(props: { editing: true | MessageVariable; onFinish: () => void }) {
  const { editing, onFinish } = props

  const initialValues = useMemo(
    () => (editing === true ? { name: '', regex: '' } : editing),
    [editing],
  )

  const [submitting, setSubmitting] = useState(false)
  const onSubmit = useCallback(
    async (values: Omit<MessageVariable, 'id'>) => {
      setSubmitting(true)
      const id = editing === true ? undefined : editing.id
      const res = await services.features.normalWelcome.addOrUpdateVariable({ id, ...values })
      setSubmitting(false)

      if (res.success) {
        void message.success('保存成功！')
        onFinish()
      } else {
        void message.warning(`保存失败：${res.error}`)
      }
    },
    [editing, onFinish],
  )

  return <Form
    styleName="form"
    initialValues={initialValues}
    labelCol={{ span: 4 }}
    onFinish={onSubmit}
  >
    <Form.Item label="变量名" name="name" rules={[{ required: true }]}>
      <Input maxLength={30} />
    </Form.Item>

    <Form.Item label="提取正则" name="regex" rules={[{ required: true }, patternRule]}>
      <Input maxLength={100} />
    </Form.Item>

    <Form.Item wrapperCol={{ offset: 4 }}>
      <Button loading={submitting} type="primary" htmlType="submit">
        保存
      </Button>
    </Form.Item>
  </Form>
}
